source("./Mean Reversion/RMR.010 Cross Validate Functions.R")pricing_data <- read_csv("./Mean Reversion/Raw Data/pricing data.csv", col_types = c("iTdddddddci")) %>%
filter(date_time < "2017-10-09")Description
A list of parameters passed to the functions below that describe the mean reversion pairs trading strategy.
Arguments
time_resolution: The number of seconds that each observation spans. Takes values 300, 900, 1800, 7200, 14400, and 86400.
quote_currency: A string indicating the quote currency of the currency pairs. Takes values “USDT” or “BTC”.
cointegration_test: A string indicating whether the Engle-Granger method or distance method is used to test for cointegration. Takes values “eg”, “tls”, or “distance”.
adf_threshold: The threshold for the ADF test statistic. Pairs below this threshold are selected when using the Engle-Granger method.
distance_threshold: The threshold for the rmse of the coins normalized prices. Pairs below this threshold are selected when using the distance method.
train_window: A lubridate period object representing the length of time the train set covers.
test_window: A lubridate period object representing the length of time the the test set covers.
model_type: A string indicating whether raw prices or log prices should be used. Takes value “raw” or “log”.
regression_type: A string indicating whether OLS, TLS, or a non-parametric regression should be used. Takes values “ols”, “tls”, or “non-parametric”.
spread_type: A string indicating whether the regression uses a rolling or fixed window. Takes value “rolling” or “fixed”.
rolling_window: The number of observations used in the lookback window of a rolling linear regression.
signal_logic: A string indicating which logic to use to generate signals. Takes values “scaled” or “discrete”.
signal_scaled_enter: The z-score threshold indicating the z-score that the signal is fully scaled in when the signal logic is scaled.
signal_discrete_enter: The z-score threshold for entering a position when the signal logic is discrete.
signal_discrete_exit: The z-score threshold for exiting a position when the signal logic is discrete.
signal_stop: A threshold for the spread z-score beyond which the strategy stops trading the coin pair.
signal_reenter: A boolean indicating whether the strategy should reenter positions after exceeding the signal_stop threshold once the spread z-score returns to a reasonable range.
signal_reenter_threshold: The z-score threshold for reentering a position if signal_reenter is TRUE. pair_allocation: A string indicating whether the capital allocation to the coin pairs should be equal or weighted. Takes values “equal”, “weighted”, and “scaled”.
pair_allocation_scaling: A double indicating the volatility scaling applied to the cointegration stat when the pair allocation is scaled. Higher numbers are associated with greater weight being placed on coin pairs with a high cointegration stat.
params <- list(time_resolution = 300,
quote_currency = "USDT",
cointegration_test = "eg",
adf_threshold = -4.0,
distance_threshold = 0.00,
train_window = days(30),
test_window = days(20),
model_type = "raw",
regression_type = "ols",
spread_type = "rolling",
rolling_window = 1440,
signal_logic = "scaled",
signal_scaled_enter = 3.0,
signal_discrete_enter = 3.0,
signal_discrete_exit = 0.2,
signal_stop = 4.5,
signal_reenter = TRUE,
signal_reenter_threshold = 2.00,
pair_allocation = "equal",
pair_allocation_scaling = 1.00)
number_pairs <- 8 plot_many(pricing_data = pricing_data,
cutoff_date = "2017-09-01",
params = params,
number_pairs = number_pairs)## # A tibble: 3 x 3
## coin_y coin_x cointegration_stat
## <chr> <chr> <dbl>
## 1 USDT_REP USDT_ZEC -5.736107
## 2 USDT_ZEC USDT_REP -5.501028
## 3 USDT_REP USDT_XMR -4.170552
plot_many(pricing_data = pricing_data,
cutoff_date = "2017-08-01",
params = params,
number_pairs = number_pairs)## # A tibble: 10 x 3
## coin_y coin_x cointegration_stat
## <chr> <chr> <dbl>
## 1 USDT_ETH USDT_ZEC -6.054465
## 2 USDT_ZEC USDT_ETH -5.967695
## 3 USDT_REP USDT_ZEC -5.783068
## 4 USDT_ZEC USDT_REP -5.717775
## 5 USDT_DASH USDT_XMR -5.299587
## 6 USDT_XMR USDT_DASH -5.189520
## 7 USDT_ETH USDT_REP -4.730916
## 8 USDT_REP USDT_ETH -4.698637
## 9 USDT_LTC USDT_ZEC -4.412000
## 10 USDT_LTC USDT_REP -4.287901
plot_many(pricing_data = pricing_data,
cutoff_date = "2017-07-01",
params = params,
number_pairs = number_pairs)## # A tibble: 8 x 3
## coin_y coin_x cointegration_stat
## <chr> <chr> <dbl>
## 1 USDT_REP USDT_XMR -8.619821
## 2 USDT_XMR USDT_REP -8.375164
## 3 USDT_REP USDT_BTC -5.951596
## 4 USDT_BTC USDT_REP -5.758097
## 5 USDT_BTC USDT_XMR -5.631816
## 6 USDT_XMR USDT_BTC -5.479049
## 7 USDT_DASH USDT_ZEC -4.102562
## 8 USDT_DASH USDT_LTC -4.007783
plot_many(pricing_data = pricing_data,
cutoff_date = "2017-06-01",
params = params,
number_pairs = number_pairs)## # A tibble: 18 x 3
## coin_y coin_x cointegration_stat
## <chr> <chr> <dbl>
## 1 USDT_REP USDT_DASH -8.229334
## 2 USDT_DASH USDT_REP -8.015776
## 3 USDT_REP USDT_XMR -6.997566
## 4 USDT_XMR USDT_REP -6.733495
## 5 USDT_DASH USDT_XMR -6.576085
## 6 USDT_XMR USDT_DASH -6.568115
## 7 USDT_REP USDT_ZEC -6.472850
## 8 USDT_DASH USDT_ZEC -6.264925
## 9 USDT_ZEC USDT_DASH -6.037114
## 10 USDT_ZEC USDT_REP -5.967876
## 11 USDT_XMR USDT_ZEC -5.616863
## 12 USDT_ZEC USDT_XMR -5.376518
## 13 USDT_ZEC USDT_ETH -4.849517
## 14 USDT_ETH USDT_ZEC -4.540834
## 15 USDT_XMR USDT_BTC -4.338487
## 16 USDT_BTC USDT_XMR -4.198414
## 17 USDT_DASH USDT_ETH -4.131498
## 18 USDT_REP USDT_BTC -4.047914
plot_many(pricing_data = pricing_data,
cutoff_date = "2017-05-01",
params = params,
number_pairs = number_pairs)## # A tibble: 15 x 3
## coin_y coin_x cointegration_stat
## <chr> <chr> <dbl>
## 1 USDT_DASH USDT_ZEC -5.324670
## 2 USDT_ZEC USDT_DASH -5.132194
## 3 USDT_XMR USDT_ZEC -5.068398
## 4 USDT_REP USDT_ETH -5.046993
## 5 USDT_ZEC USDT_XMR -4.672742
## 6 USDT_DASH USDT_REP -4.627560
## 7 USDT_XMR USDT_ETH -4.555376
## 8 USDT_ETH USDT_REP -4.527189
## 9 USDT_REP USDT_DASH -4.506359
## 10 USDT_DASH USDT_ETH -4.416835
## 11 USDT_REP USDT_ZEC -4.386418
## 12 USDT_ZEC USDT_REP -4.285102
## 13 USDT_XMR USDT_DASH -4.262944
## 14 USDT_ZEC USDT_ETH -4.088190
## 15 USDT_DASH USDT_XMR -4.036158
plot_many(pricing_data = pricing_data,
cutoff_date = "2017-04-01",
params = params,
number_pairs = number_pairs)## # A tibble: 7 x 3
## coin_y coin_x cointegration_stat
## <chr> <chr> <dbl>
## 1 USDT_XMR USDT_DASH -4.629148
## 2 USDT_ZEC USDT_BTC -4.568420
## 3 USDT_BTC USDT_ZEC -4.537424
## 4 USDT_DASH USDT_XMR -4.520526
## 5 USDT_XMR USDT_ZEC -4.418915
## 6 USDT_ZEC USDT_XMR -4.347171
## 7 USDT_REP USDT_ETH -4.156905
plot_many(pricing_data = pricing_data,
cutoff_date = "2017-03-01",
params = params,
number_pairs = number_pairs)## # A tibble: 10 x 3
## coin_y coin_x cointegration_stat
## <chr> <chr> <dbl>
## 1 USDT_LTC USDT_ZEC -5.760345
## 2 USDT_LTC USDT_REP -4.973280
## 3 USDT_LTC USDT_XMR -4.944385
## 4 USDT_LTC USDT_ETH -4.838984
## 5 USDT_LTC USDT_DASH -4.653697
## 6 USDT_LTC USDT_BTC -4.550198
## 7 USDT_XMR USDT_LTC -4.252412
## 8 USDT_XMR USDT_BTC -4.148961
## 9 USDT_ZEC USDT_LTC -4.007311
## 10 USDT_XMR USDT_DASH -4.005995
plot_many(pricing_data = pricing_data,
cutoff_date = "2017-02-01",
params = params,
number_pairs = number_pairs)## # A tibble: 12 x 3
## coin_y coin_x cointegration_stat
## <chr> <chr> <dbl>
## 1 USDT_REP USDT_BTC -5.161710
## 2 USDT_REP USDT_ETH -5.138239
## 3 USDT_REP USDT_XMR -5.002405
## 4 USDT_REP USDT_ZEC -4.994983
## 5 USDT_REP USDT_DASH -4.777125
## 6 USDT_LTC USDT_XMR -4.582033
## 7 USDT_REP USDT_LTC -4.561970
## 8 USDT_ETH USDT_DASH -4.357336
## 9 USDT_LTC USDT_ZEC -4.207423
## 10 USDT_XMR USDT_LTC -4.158443
## 11 USDT_ETH USDT_REP -4.146677
## 12 USDT_ZEC USDT_LTC -4.114974
plot_many(pricing_data = pricing_data,
cutoff_date = "2017-01-01",
params = params,
number_pairs = number_pairs)## # A tibble: 9 x 3
## coin_y coin_x cointegration_stat
## <chr> <chr> <dbl>
## 1 USDT_REP USDT_XMR -6.684626
## 2 USDT_REP USDT_ETH -6.074812
## 3 USDT_REP USDT_LTC -5.994885
## 4 USDT_REP USDT_BTC -5.820387
## 5 USDT_REP USDT_ZEC -5.788823
## 6 USDT_REP USDT_DASH -5.754398
## 7 USDT_LTC USDT_BTC -4.235045
## 8 USDT_ETH USDT_REP -4.225974
## 9 USDT_LTC USDT_XMR -4.003757
results <- backtest_strategy_full(pricing_data = pricing_data,
params = params) ## [1] "Cross validating strategy."
## [1] "Using train set from 2016-12-02 to 2017-01-01."
## [1] "Using test set from 2017-01-01 to 2017-01-21."
## [1] "Cross validating strategy."
## [1] "Using train set from 2016-12-22 to 2017-01-21."
## [1] "Using test set from 2017-01-21 to 2017-02-10."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-01-11 to 2017-02-10."
## [1] "Using test set from 2017-02-10 to 2017-03-02."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-01-31 to 2017-03-02."
## [1] "Using test set from 2017-03-02 to 2017-03-22."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-02-20 to 2017-03-22."
## [1] "Using test set from 2017-03-22 to 2017-04-11."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-03-12 to 2017-04-11."
## [1] "Using test set from 2017-04-11 to 2017-05-01."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-04-01 to 2017-05-01."
## [1] "Using test set from 2017-05-01 to 2017-05-21."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-04-21 to 2017-05-21."
## [1] "Using test set from 2017-05-21 to 2017-06-10."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-05-11 to 2017-06-10."
## [1] "Using test set from 2017-06-10 to 2017-06-30."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-05-31 to 2017-06-30."
## [1] "Using test set from 2017-06-30 to 2017-07-20."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-06-20 to 2017-07-20."
## [1] "Using test set from 2017-07-20 to 2017-08-09."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-07-10 to 2017-08-09."
## [1] "Using test set from 2017-08-09 to 2017-08-29."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-07-30 to 2017-08-29."
## [1] "Using test set from 2017-08-29 to 2017-09-18."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-08-19 to 2017-09-18."
## [1] "Using test set from 2017-09-18 to 2017-10-08."
ggplot(results, aes(x = date_time)) +
geom_line(aes(y = return_strategy_cumulative), colour = "blue", size = 1) +
geom_hline(yintercept = 1, colour = "black") +
labs(title = "Strategy Return vs Buy Hold Return", x = "Date", y = "Cumulative Return") print(results[["return_strategy_cumulative"]][nrow(results)]) ## [1] 167.2748